'use strict';

module.exports = core;
const path = require('path');
const pkg = require('../package.json');
const log = require("@duo-cli/log");
const init = require('@duo-cli/init');
const exec = require('@duo-cli/exec');
const colors = require('colors/safe');
const constant = require('./const');
const userHome = require('user-home');
const commander = require('commander');
const pathExists = require('path-exists').sync;
const semver = require('semver');

const program = new commander.Command();

async function core() {
    try {
        prepare();
        registerCommand();
    } catch (error) {
        log.error(error.message);
        if (process.env.LOG_LEVEL === 'verbose') {
            console.log(error);
        }
    }
} 

async function prepare() {
    // cli版本
    checkPkgVersion();
    // node版本
    checkNodeVersion();
    // 检查root权限
    checkRoot();
    // 检查用户主目录
    checkUserHome();
    // 检查环境变量
    checkEnv();
    // 检查更新
    await checkGlobalUpdate();
}

function registerCommand() {
    program
        .name(Object.keys(pkg.bin)[0])
        .usage('<command> [options]')
        .version(pkg.version)
        .option('-d, --debug', '是否开启调试模式', false)
        .option('-t, --targetPath <targetPath>', '是否指定本地调试文件路径', "");

    program
        .command('init [projectName]')
        .option('-f, --force', '是否强制初始化项目')
        .description('初始化项目')
        .action(exec);
        
    program.on("option:debug",  function() {
        process.env.LOG_LEVEL = "verbose";
        log.level = process.env.LOG_LEVEL;
    })

    program.on("option:targetPath",  function() {
        process.env.CLI_TARGET_PATH = program.opts().targetPath;
    })

    program.on("command:*", function(obj) {
        const availableCommands = program.commands.map(cmd => cmd.name());
        log.error(colors.red(`未知的命令 ${obj[0]}`));
        if (availableCommands.length > 0) {
            log.info(colors.yellow(`可用命令：${availableCommands.join(',')}`));
        }
    });

    program
        .parse(process.argv);
        
    if (program.args && program.args.length < 1) {
        program.outputHelp();
        console.log("");
    }
}

async function checkGlobalUpdate() {
    // 1. 获取当前版本号和模块名
    const currentVersion = pkg.version;
    const npmName = pkg.name;
    const { getNpmSemverVersion } = require('@duo-cli/get-npm-info');
    const lastVersion = await getNpmSemverVersion(currentVersion, npmName);
    if (lastVersion && semver.gt(lastVersion, currentVersion)) {
        console.log("");
        log.warn(colors.yellow(`请手动更新 ${npmName}, 当前版本: ${currentVersion}, 最新版本: ${lastVersion}`));
        log.warn(colors.yellow(`更新命令: npm i ${npmName} -g`));
        console.log("");
    }
}

function checkEnv() {
    const dotenv = require('dotenv');
    const dotenvPath = path.resolve(userHome, '.env');
    if (pathExists(dotenvPath)) {
        dotenv.config({path: dotenvPath});
    } else {
        createDefaultConfig();
    }
}

function createDefaultConfig() {
    const cliConfig = {
        home: userHome 
    }
    if (process.env.CLI_HOME) {
        cliConfig['cliHome'] = path.join(userHome, process.env.CLI_HOME);
    } else {
        cliConfig['cliHome'] = path.join(userHome, constant.DEFAULT_CLI_HOME);
    }
    process.env.CLI_HOME_PATH = cliConfig['cliHome'];
    return cliConfig;
}

function checkUserHome() {
    if (!userHome || !pathExists(userHome)) {
        throw new Error(colors.red('当前登录用户主目录不存在'));
    }
}

function checkRoot() {
    const rootCheck = require('root-check');
    rootCheck();
}

function checkNodeVersion() {
    const currentVersion = process.version;
    const lowestVersion = constant.LOWEST_NODE_VERSION;
    if (!semver.gte(currentVersion, lowestVersion)) {
        throw new Error(
            colors.red(`duo-cli 需要安装 v${lowestVersion} 以上版本的 node. 当前版本为 ${currentVersion}`)
        );
    }
}

function checkPkgVersion() {
    log.notice("cli", pkg.version)
}